#include "BSP.h"
#include "math.h"

#define LASER_PWM_HANDLER   htim2
#define LASER_PWM_CHANNEL   TIM_CHANNEL_2

#define OFF_POWER   HAL_GPIO_WritePin(GPO_Power_GPIO_Port,GPO_Power_Pin,GPIO_PIN_RESET)
#define ON_POWER    HAL_GPIO_WritePin(GPO_Power_GPIO_Port,GPO_Power_Pin,GPIO_PIN_SET)

#define EMIT_TRIG   HAL_GPIO_WritePin(GPO_Emit_GPIO_Port,GPO_Emit_Pin,GPIO_PIN_RESET)
#define EMIT_STAY   HAL_GPIO_WritePin(GPO_Emit_GPIO_Port,GPO_Emit_Pin,GPIO_PIN_SET)

#define CAP_CHARG   HAL_GPIO_WritePin(GPO_Cap_GPIO_Port,GPO_Cap_Pin,GPIO_PIN_SET)
#define CAP_EMIT    HAL_GPIO_WritePin(GPO_Cap_GPIO_Port,GPO_Cap_Pin,GPIO_PIN_RESET)

#define delay(X)    rt_thread_mdelay(X)

double laser_A = 18.3,laser_B = 4;

/** @brief  初始化电磁炮相关外设
 *  @note   包括GPO和激光亮度PWM
 *  @author 江榕煜（2021.6.15）
 *  @param  None
 *  @retval None
**/
void magneticEmit_Init(void)
{
//    magneticEmitCtrl(standby);  // 电磁炮发射进入待命状态
    EMIT_STAY;
    OFF_POWER;
    CAP_EMIT;
    
    HAL_TIM_PWM_Start(&LASER_PWM_HANDLER,LASER_PWM_CHANNEL);    // 使能激光镭射输出
    
}

/** @brief  激光控制
 *  @note   
 *  @author 江榕煜（2021.6.15）
 *  @param  亮度百分比
 *  @retval None
**/
void laserCtrl(float duty)
{
    //duty = duty * 9.999;
    static char cache[60];
//    duty = laser_A * log(laser_B * duty+1);
    duty = laser_A * (exp(laser_B * duty/100)-1);
    sprintf(cache,"激光驱动:%lf",duty);
    rt_kprintf(cache);
    
    LASER_PWM_HANDLER.Instance->CCR2 = duty;    // 最大1000
}

/** @brief  电磁炮控制！
 *  @note   
 *  @author 江榕煜（2021.6.15）
 *  @param  
 *      statusCmd(magneticEmitStatus)   状态命令
 *  @retval
**/
void magneticEmitCtrl(magneticEmitStatus statusCmd)
{
    switch(statusCmd)
    {
        case(standby):
            // 先切断电源，关闭发射触发，再切换电容
            EMIT_STAY;
            OFF_POWER;
            delay(500);
            CAP_EMIT;
            delay(500);
            break;
        case(charge):
            // 关闭发射；切换电容；打开电源
            EMIT_STAY;
            CAP_CHARG;
            delay(500);
            ON_POWER;
            delay(500);
            break;
        case(EMIT):
            // 确定关闭发射；关闭电源；切换电容；发射；关闭发射
            EMIT_STAY;
            OFF_POWER;
            delay(500);
            CAP_EMIT;
            delay(500);
            EMIT_TRIG;
            delay(1);
            EMIT_STAY;
            break;
    }
}

/* --- 用户接口 --- */

void laser(int argn,char ** argv)
{
    if(argn < 2)
    {
        rt_kprintf("参数错误 \n");
        return;
    }
    
//    switch(argv[1][0])
//    {
//        case('0'):
//            laserCtrl(0);
//            break;
//        case('1'):
//            laserCtrl(25);
//            break;
//        case('2'):
//            laserCtrl(50);
//            break;
//        case('3'):
//            laserCtrl(75);
//            break;
//        case('4'):
//            laserCtrl(100);
//            break;
//    }
    float cache;
    sscanf(argv[1],"%f",&cache);
    laserCtrl(cache);
    rt_kprintf("使用激光注意保护眼睛 \n");
    return;
}
MSH_CMD_EXPORT(laser,镭射控制);

void laserFix(int argn,char ** argv)
{
    if(argn <2)
    {
        rt_kprintf("参数数量错误 \n");
        return;
    }
    
    sscanf(argv[1],"%lf",&laser_B);
//    laser_A = 1000/log(laser_B*100);
    laser_A = 1000/(exp(laser_B)-1);
    
    rt_kprintf("设置激光矫正成功\n");
}
MSH_CMD_EXPORT(laserFix,镭射矫正);
